package top.rish.universe.core.app;

import org.noear.socketd.SocketD;
import org.noear.socketd.transport.core.Message;
import org.noear.socketd.transport.core.Session;
import org.noear.socketd.transport.core.entity.StringEntity;
import org.noear.socketd.transport.core.listener.SimpleListener;
import org.noear.solon.core.*;
import org.noear.solon.core.event.*;
import org.noear.solon.core.util.LogUtil;
import top.rish.universe.core.plugin.PluginRestartEndEvent;
import top.rish.universe.core.plugin.UniPluginUtil;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class AppCorePluginImpl implements Plugin {
    public static final Map<String, Session> SESSION_MAP = new HashMap<>();

    @Override
    public void start(AppContext context) throws Throwable {

        EventBus.subscribe(AppPluginLoadEndEvent.class,(app)->{
            UniPluginUtil.loadUniversePlugins();
            hotSwapDevServer();
        });

        EventBus.subscribe(PluginRestartEndEvent.class,(app)->{
            String pluginId = app.getPluginId();
            for (Session session : SESSION_MAP.values()) {
                try {
                    session.send("/plugin-hot-swap/"+pluginId, new StringEntity("plugin is restarted"));
                } catch (IOException e) {
                    LogUtil.global().warn(e.getMessage());
                }
            }
            LogUtil.global().info( pluginId  +" hot swap ok !");
        });

    }

    public static void hotSwapDevServer() throws IOException {
        SocketD.createServer("sd:ws")
                .config(c -> c.port(8602))
                .listen(new SimpleListener() {
                    @Override
                    public void onMessage(Session session, Message message) throws IOException {
                        session.reply(message, new StringEntity("ok"));
                    }

                    @Override
                    public void onOpen(Session session) throws IOException {
                        super.onOpen(session);
                        SESSION_MAP.put(session.sessionId(), session);
                    }

                    @Override
                    public void onClose(Session session) {
                        super.onClose(session);
                        SESSION_MAP.remove(session.sessionId());
                    }
                })
                .start();
    }



    @Override
    public void prestop() throws Throwable {
        Plugin.super.prestop();
    }

    @Override
    public void stop() throws Throwable {
        Plugin.super.stop();
    }
}
